"""
Created on 13 mrt. 2012

@author: Daan
"""

import sys
import os

sys.path.append( os.path.join( os.getcwd(), ".." ) )

import datetime
import time
import xmlrpclib
import socket

from pCommon import PortList

class PhotoClient:
    """
    """

    def __init__( self, loopInterval, filescanInterval, machineManagerUpdateInterval, watchDirectory,
                  name = "PhotoClient",
                  extensions = None ):

        self.CLIENT = [name, PortList.PHOTOCLIENT]
        self.HOST = "http://localhost:%s" % PortList.CENTRALSERVER

        self.updateMachineListCountdown = 0
        self.filescanIntervalCountdown = 0
        self.offlineCounter = 0
        self.proxy = None
        self.machineList = []
        self.filesToSend = []

        self.watchDirectory = watchDirectory
        self.loopInterval = loopInterval
        self.updateMachineListInterval = machineManagerUpdateInterval // 2
        self.filescanInterval = filescanInterval
        self.extensions = extensions or []

        try:
            self.filescanStoredDict = {f: None for f in os.listdir( self.watchDirectory ) if any( f.endswith( e ) for e in self.extensions )}
        except ( IOError, WindowsError ) as e:
            self.filescanStoredDict = {}
        except Exception as e:
            raise e


    def updateMachineList( self ):
        """
        """

        self.updateMachineListCountdown += self.loopInterval

        if self.updateMachineListCountdown >= self.updateMachineListInterval:
            self.updateMachineListCountdown = 0
            try:
                self.proxy.registerMachine( self.CLIENT )
                self.machineList = self.proxy.retrieveMachines()

            except socket.error:
                self.machineList = []

    def checkForFileUpdates( self ):
        """
        """

        self.filesToSend = []

        self.filescanIntervalCountdown += self.loopInterval

        if self.filescanIntervalCountdown >= self.filescanInterval:
            self.filescanIntervalCountdown = 0

            try:
                newFilesDict = {f: None for f in os.listdir( self.watchDirectory ) if any( f.endswith( e ) for e in self.extensions )}
                added = [f for f in newFilesDict if not f in self.filescanStoredDict]
                #removed = [f for f in self.filescaneStoredDict if not f in newFilesDict]

                self.filesToSend = added
                self.filescanStoredDict = newFilesDict
            except ( IOError, WindowsError ):
                pass
            except Exception as e:
                raise e

    def sendFiles( self ):
        """
        """

        filesToSend = [[f, 3] for f in self.filesToSend]

        while len( filesToSend ) > 0:
            entry = filesToSend.pop( 0 )
            fileToSend = os.path.join( self.watchDirectory, entry[0] )

            retry = True
            try:
                with open( fileToSend, "rb" ) as handle:
                    if self.proxy.storeFile( fileToSend, [datetime.datetime.now()], xmlrpclib.Binary( handle.read() ) ):
                        retry = False
            except Exception as e:
                print e

            if retry:
                print "retrying:", fileToSend, entry[1]
                entry[1] -= 1
                if not ( entry[1] <= 0 ):
                    filesToSend.append( entry )

    def __enter__( self ):
        return self

    #noinspection PyUnusedLocal
    def __exit__( self, exc_type, exc_val, exc_tb ):
        try:
            self.proxy.shutdown()
        except Exception:
            pass


    def run( self ):
        """
        """

        self.proxy = xmlrpclib.ServerProxy( self.HOST )

        try:
            self.proxy.registerMachine( self.CLIENT )
        except Exception:
            print "No connection could be made"
            return False

        while True:
            self.updateMachineList()

            self.checkForFileUpdates()

            self.sendFiles()

            time.sleep( self.loopInterval )
